package com.pmcc.core.service;

import com.pmcc.core.entity.Organization;
import com.pmcc.core.repository.OrganizationRepository;
import com.pmcc.core.vo.OrgVo;
import com.pmcc.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by tomas on 2018/4/9.
 */
@Service
@Transactional
public class OrganizationService {
    @Autowired
    OrganizationRepository organizationRepository;

    public ResultBean queryByPage(AntdPage antdPage, Organization model){
        ResultBean resultBean = new ResultBean(ResultBean.SUCCESS);
        try {
            Page page=organizationRepository.findAll(this.getSpecification(model),antdPage.getPageRequest());
            resultBean.setPage(antdPage.getDefaultCurrent());
            resultBean.setTotal(page.getTotalElements());
            resultBean.setPageSize(antdPage.getPageSize());
            resultBean.setRows(page.getContent());
        }catch (Exception e){
            resultBean.setResultCode(ResultBean.FAIL);
        }
        return resultBean;
    }
    public Specification<Organization> getSpecification(Organization model) {
        return new Specification<Organization>() {
            @Override
            public Predicate toPredicate(Root<Organization> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                List<Predicate> list = new ArrayList<Predicate>();
                if(StringUtil.isNotEmpty(model.getName())&&model.getName()!=null){
                    list.add(builder.like(root.get("name").as(String.class),  "%"+model.getName().trim()+"%"));
                }
                Predicate[] p = new Predicate[list.size()];
                return builder.and(list.toArray(p));
            }
        };
    }
    public ResultBean addOrganization(Organization model) {
        ResultBean resultBean = new ResultBean(ResultBean.SUCCESS);
        try {
            model.setCreateTime(new Date());
            model.setCreator(OnlineUser.getName());
            //生成自增长编码
            model.setCode(createAddMark(model.getParentId()));
            organizationRepository.saveAndFlush(model);
        }catch (Exception e){
            resultBean.setResultCode(ResultBean.FAIL);
        }
        return resultBean;
    }

    /**
     * 返回新增的可变长 机构增长码
     *
     * @param parentId 所选上级机构id
     * @return
     */

    public String createAddMark(String parentId) {
        String str = "";
        List<Organization> list = new ArrayList<>();
        if ("root".equals(parentId)) {
            list = organizationRepository.findByParentId(parentId);
            if (list != null && list.size() > 0) {
                int n = 0;
                for (int m = 1; m <= 99; m++) {
                    String tr = m <= 9 ? "0"+m : m + "";
                    List<Organization> organizationList = organizationRepository.findByParentIdAndCode("root", tr);
                    if (organizationList == null || organizationList.size() <= 0) {
                        n = m;
                        break;
                    }
                }
                if(n<=9){
                    str = "0"+ n ;
                }else {
                    str = n + "";
                }
            } else {
                str = 0 + "1";
            }
        } else {
            String parentCode = organizationRepository.getOne(parentId).getCode();
            list = organizationRepository.findByParentId(parentId);
            if (list != null && list.size() > 0) {
                if (judgeAndNew(parentCode + createStr(list.size(), parentId))) {
                    int i = 1;
                    while (true) {
                        if (!judgeAndNew(parentCode + createStr(list.size() + i, parentId))) {
                            str = parentCode + createStr(list.size() + i, parentId);
                            break;
                        }
                        i++;
                    }
                } else {
                    str = parentCode + createStr(list.size(), parentId);
                }
            } else {
                str = parentCode + "01";
                /*if ("".equals(organizationDao.get(parentId).getParentId()) || (organizationDao.get(parentId).getParentId()) == null) {
                    str = parentCode + "1";
                } else {
                    str = parentCode + "01";
                }*/
            }
        }
        return str;
    }
    /**
     * 根据对应 整数 生成最少两位字符串
     *
     * @param m
     * @return
     */
    public String createStr(int m, String parentId) {
        String str = "";
        if (m <= 9) {
            if ("root".equals(organizationRepository.getOne(parentId))) {
                str = "0" + m;
            } else {
                str = "0" + m;//新编码
            }
        } else {
            if(m>=100){
                List<String> list=this.buildString();
                str=list.get(m-100);
            }else {
                str = "" + m;
            }
        }
        return str;
    }
    /**
     * 判断生成 编码是否 已被使用
     *
     * @param newCode
     * @return
     */
    public boolean judgeAndNew(String newCode) {
        List<Organization> list = organizationRepository.findByCode(newCode);
        if (list != null && list.size() > 0) {
            return true;//已被占有
        } else {
            return false;//可以使用
        }
    }
    public List<String> buildString(){
        List<String> list=new ArrayList<>();
        String[] str={"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
        for(String s:str){
            for(int i=0;i<10;i++){
                list.add(s+i);
            }
        }
        for(String s:str){
            for(int i=0;i<10;i++){
                list.add(i+s);
            }
        }
        return list;
    }
    public ResultBean editOrganization(Map map) {
        ResultBean resultBean = new ResultBean(ResultBean.SUCCESS);
        try {
            Organization c = organizationRepository.findOne(map.get("id").toString());
            BeanUtils.setBeanData(c, map);
            organizationRepository.saveAndFlush(c);
        }catch (Exception e){
            resultBean.setResultCode(ResultBean.FAIL);
        }
        return resultBean;
    }
    public ResultBean deleteOrganization(String id) {
        ResultBean resultBean =new ResultBean(ResultBean.SUCCESS);
        try {
            organizationRepository.delete(id);
        }catch (Exception e){
            resultBean.setResultCode(ResultBean.FAIL);
        }
        return resultBean;
    }
    public  ResultBean queryComBo(){
        ResultBean resultBean = new ResultBean();
        resultBean.setResultCode(ResultBean.SUCCESS);
        try{
            List<Organization> list = organizationRepository.findAll();
            resultBean.setRows(list);
        }catch (Exception e){
            resultBean.setResultCode(ResultBean.FAIL);
        }
        return  resultBean;
    }
    public ResultBean queryTreeGrid() {
        ResultBean resultBean = new ResultBean(ResultBean.SUCCESS);
        try {
            resultBean.setRows(this.queryList());
        }catch (Exception e){
            resultBean.setResultCode(ResultBean.FAIL);
        }
        return resultBean;
    }
    public List<OrgVo> queryList() {
        List<OrgVo> list = null;
        OrgVo orgVo = null;
        Organization organization = new Organization();
        organization.setId("root");
        OrgVo vo = OrgVo.getOrgVo(organization);
        orgVo = this.traversalOrg(vo);
        return orgVo.getChildren();
    }
    public OrgVo traversalOrg(OrgVo orgVo) {
        List<Organization> organizations = organizationRepository.findByParentIdOrderByCodeAsc(orgVo.getId());
        List<OrgVo> eleNodeVos = new ArrayList<>();
        if (organizations.size() > 0) {
            for (Organization o : organizations) {
                OrgVo vo = OrgVo.getOrgVo(o);
                OrgVo eleNodeVo2 = this.traversalOrg(vo);
                eleNodeVos.add(eleNodeVo2);
            }
            orgVo.setChildren(eleNodeVos);
        }
        return orgVo;
    }
}
